package es.tikitaka.actions.jugadores;

import java.util.Iterator;
import java.util.List;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.faces.FacesMessages;

import es.tikitaka.dao.EquipoService;
import es.tikitaka.dao.JugadorService;
import es.tikitaka.dao.MunicipioDicService;
import es.tikitaka.dao.PosicionDicService;
import es.tikitaka.dao.ProvinciaDicService;
import es.tikitaka.dao.TemporadaService;
import es.tikitaka.dictionary.MunicipioDic;
import es.tikitaka.dictionary.PosicionDic;
import es.tikitaka.dictionary.ProvinciaDic;
import es.tikitaka.domain.Temporada;
import es.tikitaka.domain.equipo.Equipo;
import es.tikitaka.domain.jugador.Jugador;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */

@Name("jugadorSearch")
@Scope(ScopeType.CONVERSATION)
public class JugadorSearch {

	private int modo;
	private int pestania;

	private Jugador jugadorElim;
	private Jugador jugadorBaja;
	private Jugador jugadorAlta;

	private String nombre;
	private String apellidos;
	private Temporada temporada;
	private Equipo equipo;
	private ProvinciaDic provincia;
	private MunicipioDic municipio;
	private Integer edad;
	private PosicionDic posicion;
	private int activo = 1;

	private String nombreLote;
	private String apellidosLote;
	private Equipo equipoLote;
	private ProvinciaDic provinciaLote;
	private MunicipioDic municipioLote;

	private int totalRes;
	private int totalResLote;

	private List<ProvinciaDic> listaProvincias;
	private List<MunicipioDic> listaMunicipios;
	private List<Temporada> listaTemporadas;
	private List<Equipo> listaEquipos;
	private List<PosicionDic> listaPosiciones;

	private List<ProvinciaDic> listaProvinciasLote;
	private List<MunicipioDic> listaMunicipiosLote;

	private List<Jugador> jugadoresBus;
	private List<Jugador> jugadoresSel;

	@DataModel("jugadores")
	private List<Jugador> jugadores;
	@DataModelSelection("jugadores")
	private Jugador jugadorItem;

	@In(create = true)
	private JugadorService jugadorService;

	@In(create = true)
	private ProvinciaDicService provinciaService;

	@In(create = true)
	private MunicipioDicService municipioService;

	@In(create = true)
	private PosicionDicService posicionService;

	@In(create = true)
	private EquipoService equipoService;

	@In(create = true)
	private TemporadaService temporadaService;

	/**
	 * Constructor por defecto
	 */
	public JugadorSearch() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Método que inicializa la variable modo para que en la pantalla de
	 * búsqueda se cargen las opciones de eliminar
	 */
	public void modoEliminar() {
		modo = 1;
		cargaOpcionesBusqueda();
	}

	/**
	 * Método que inicializa la variable modo para que en la pantalla de
	 * búsqueda se cargen las opciones de edición
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void modoEdicion() {
		modo = 2;
		cargaOpcionesBusqueda();
	}

	/**
	 * Método que inicializa la variable modo para que en la pantalla de
	 * búsqueda se cargen las opciones de consulta
	 */
	public void modoConsulta() {
		modo = 3;
		cargaOpcionesBusqueda();
	}

	/**
	 * Método que inicializa la variable modo para que en la pantalla de
	 * búsqueda se cargen las opciones de alta
	 */
	public void modoAlta() {
		modo = 4;
		cargaOpcionesBusqueda();
	}

	/**
	 * Método que inicializa la variable modo para que en la pantalla de
	 * búsqueda se cargen las opciones de baja
	 */
	public void modoBaja() {
		modo = 5;
		cargaOpcionesBusqueda();
	}

	/**
	 * Método que carga las opciones en la pantalla de búsqueda de jugadores
	 */
	public void cargaOpcionesBusqueda() {
		listaProvincias = provinciaService.getList();
		listaPosiciones = posicionService.getList();
		listaEquipos = equipoService.getList();
		listaTemporadas = temporadaService.getList();
		listaProvinciasLote = provinciaService.getList();
	}

	/**
	 * Método para buscar jugadores según los criterios de consulta
	 */
	@Begin(join = true)
	public void buscar() {

		StringBuffer s = new StringBuffer();

		if (modo == 4) {
			// Busca a los jugadores que se encuentran inactivos en este momento
			s
					.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
			s
					.append("left join fetch j.m_jugadores g left join fetch g.temporada t where j.activo = 'false' ");
		} else if (modo == 5) {
			// Busca a los jugadores que se encuentran activos en este momento
			s
					.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
			s
					.append("left join fetch j.m_jugadores g left join fetch g.temporada t where j.activo = 'true' ");
		} else {
			// Busca a todos los jugadores según el estado seleccionado
			if (activo == 1) {
				s
						.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
				s
						.append("left join fetch j.m_jugadores g left join fetch g.temporada t where j.activo = 'true' ");
			} else if (activo == 2) {
				s
						.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
				s
						.append("left join fetch j.m_jugadores g left join fetch g.temporada t where j.activo = 'false' ");
			}
		}

		if (nombre != null && nombre.length() > 0) {
			s.append("and upper(j.nombre) like upper('%'||?1||'%') ");
		}
		if (apellidos != null && apellidos.length() > 0) {
			s.append("and upper(j.apellidos) like upper('%'||?2||'%') ");
		}
		if (edad != null) {
			s.append(" and g.edad = ?3 ");
		}
		if (temporada != null) {
			s.append("and g.temporada.id = ?4 ");
		}
		if (equipo != null) {
			s.append("and g.equipo.id = ?5 ");
		}
		if (provincia != null) {
			s.append("and p.id = ?6 ");
		}
		if (municipio != null) {
			s.append("and m.id = ?7 ");
		}
		if (posicion != null) {
			s.append("and g.posicion.id = ?8 ");
		}
		s.append("order by j.apellidos, j.nombre");
		jugadores = jugadorService.buscar(nombre, apellidos, temporada, equipo,
				provincia, municipio, edad, posicion, s);
		totalRes = jugadores.size();
	}

	/**
	 * Método para buscar jugadores según los criterios de consulta para ser
	 * dados de alta por lotes
	 */
	public void buscarAltaPorLote() {

		StringBuffer s = new StringBuffer();

		s
				.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
		s.append("left join fetch j.m_jugadores g where j.activo = 'false' ");

		if (nombreLote != null && nombreLote.length() > 0) {
			s.append("and upper(j.nombre) like upper('%'||?1||'%') ");
		}
		if (apellidosLote != null && apellidosLote.length() > 0) {
			s.append("and upper(j.apellidos) like upper('%'||?2||'%') ");
		}
		if (equipoLote != null) {
			s.append("and g.equipo.id = ?5 ");
		}
		if (provinciaLote != null) {
			s.append("and p.id = ?6 ");
		}
		if (municipioLote != null) {
			s.append("and m.id = ?7 ");
		}

		s.append("order by j.apellidos, j.nombre");

		jugadoresBus = jugadorService.buscar(nombreLote, apellidosLote, null,
				equipoLote, provinciaLote, municipioLote, null, null, s);

		totalResLote = jugadoresBus.size();
	}

	/**
	 * Método para buscar jugadores según los criterios de consulta para ser
	 * dados de baja por lotes
	 */
	public void buscarBajaPorLote() {

		StringBuffer s = new StringBuffer();

		s
				.append("select j from Jugador j left join fetch j.provincia p left join fetch j.municipio m ");
		s.append("left join fetch j.m_jugadores g where j.activo = 'true' ");

		if (nombreLote != null && nombreLote.length() > 0) {
			s.append("and upper(j.nombre) like upper('%'||?1||'%') ");
		}
		if (apellidosLote != null && apellidosLote.length() > 0) {
			s.append("and upper(j.apellidos) like upper('%'||?2||'%') ");
		}
		if (equipoLote != null) {
			s.append("and g.equipo.id = ?5 ");
		}
		if (provinciaLote != null) {
			s.append("and p.id = ?6 ");
		}
		if (municipioLote != null) {
			s.append("and m.id = ?7 ");
		}

		s.append("order by j.apellidos, j.nombre");

		jugadoresBus = jugadorService.buscar(nombreLote, apellidosLote, null,
				equipoLote, provinciaLote, municipioLote, null, null, s);

		totalResLote = jugadoresBus.size();
	}

	/**
	 * Método que selecciona a un jugador para su eliminación
	 * 
	 * @param jugador
	 *            Jugador a eliminar
	 */
	public void eliminar(Jugador jugador) {
		jugadorElim = jugador;
	}

	/**
	 * Método para eliminar a un jugador del sistema
	 */
	public void eliminar() {
		if (jugadorElim != null) {
			if (jugadorElim.getM_jugadores() != null
					&& jugadorElim.getM_jugadores().size() > 0) {
				FacesMessages
						.instance()
						.add(
								"No se puede eliminar el jugador porque tiene datos de temporadas.");
			} else {
				boolean b = jugadorService.delete(jugadorElim.getId());
				if (b) {
					FacesMessages
							.instance()
							.add(
									"El jugador seleccionado se ha eliminado correctamente.");
				} else {
					FacesMessages.instance().add(
							"El jugador no se ha podido eliminar del sistema.");
				}
			}
		}
	}

	/**
	 * Método que selecciona a un jugador para su baja
	 * 
	 * @param jugador
	 */
	public void baja(Jugador jugador) {
		jugadorBaja = jugador;
	}

	/**
	 * Método para dar de baja a un jugador en el sistema
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void baja() {
		if (jugadorBaja != null) {
			jugadorBaja.setActivo(false);
			boolean b = jugadorService.save(jugadorBaja);
			if (b) {
				jugadores.remove(jugadorBaja);
				totalRes = jugadores.size();
				FacesMessages.instance().add(
						"El jugador ha sido dado de baja correctamente.");
			} else {
				FacesMessages
						.instance()
						.add(
								"Se ha producido un error y no se ha podido dar la baja al jugador.");
			}
		} else {
			FacesMessages.instance().add(
					"No hay ningún jugador seleccionado para dar la baja");
		}
	}

	/**
	 * Método que selecciona a un jugador para su alta
	 * 
	 * @param jugador
	 */
	public void alta(Jugador jugador) {
		jugadorAlta = jugador;
	}

	/**
	 * Método para dar de alta a un jugador en el sistema
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void alta() {

		if (jugadorAlta != null) {
			jugadorAlta.setActivo(true);
			boolean b = jugadorService.save(jugadorAlta);
			if (b) {
				jugadores.remove(jugadorAlta);
				totalRes = jugadores.size();
				FacesMessages.instance().add(
						"El jugador ha sido dado de alta correctamente.");
			} else {
				FacesMessages
						.instance()
						.add(
								"Se ha producido un error y no se ha podido dar el alta al jugador.");
			}
		} else {
			FacesMessages.instance().add(
					"No hay ningún jugador seleccionado para dar el alta");
		}

	}

	/**
	 * Método para dar de alta a un conjunto de jugadores
	 */
	@SuppressWarnings("unchecked")
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void altaPorLote() {

		if (jugadoresSel != null && jugadoresSel.size() > 0) {
			Iterator it = jugadoresSel.iterator();
			boolean b = true;
			while (it.hasNext() && b) {
				Jugador j = (Jugador) it.next();
				j.setActivo(true);
				b = jugadorService.save(j);
			}

			if (b) {
				FacesMessages
						.instance()
						.add(
								"Se ha dado de alta correctamente al conjunto de jugadores");
			} else {
				FacesMessages
						.instance()
						.add(
								"Se ha producido un error y no se ha podido dar de alta a todo el conjunto de jugadores");
			}
		}
	}

	/**
	 * Método para dar de baja a un conjunto de jugadores
	 */
	@SuppressWarnings("unchecked")
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void bajaPorLote() {

		if (jugadoresSel != null && jugadoresSel.size() > 0) {
			Iterator it = jugadoresSel.iterator();
			boolean b = true;
			while (it.hasNext() && b) {
				Jugador j = (Jugador) it.next();
				j.setActivo(false);
				b = jugadorService.save(j);
			}

			if (b) {
				FacesMessages
						.instance()
						.add(
								"Se ha dado de baja correctamente al conjunto de jugadores");
			} else {
				FacesMessages
						.instance()
						.add(
								"Se ha producido un error y no se ha podido dar de baja a todo el conjunto de jugadores");
			}
		}
	}

	/**
	 * Método para limpiar los criterios de búsqueda del formularios
	 */
	public void limpiar() {
		// limpiado de criterios individuales
		nombre = null;
		apellidos = null;
		temporada = null;
		equipo = null;
		provincia = null;
		municipio = null;
		edad = null;
		posicion = null;
		jugadores = null;
		listaMunicipios = null;
		// limpiado de criterios por lotes
		nombreLote = null;
		apellidosLote = null;
		equipoLote = null;
		provinciaLote = null;
		municipioLote = null;
		jugadoresBus = null;
		jugadoresSel = null;
		listaMunicipiosLote = null;
	}

	/**
	 * Método para inicializar todos los parámetros al volver al menú de
	 * jugadores
	 */
	@End
	public void volver() {
		limpiar();
	}

	/**
	 * Método para inicializar todos los parámetros al volver al menú principal
	 */
	@End
	public void menu() {
		limpiar();
	}

	/**
	 * Método para mostrar botones en la botonera dependiendo de la pestaña
	 * seleccionada
	 * 
	 * @param pes
	 *            Pestaña seleccionada
	 */
	public void cambiaPestania(int pes) {
		pestania = pes;
	}

	/*
	 * getters and setters
	 */

	/**
	 * 
	 * @return
	 */
	public int getModo() {
		return modo;
	}

	/**
	 * 
	 * @param modo
	 */
	public void setModo(int modo) {
		this.modo = modo;
	}

	/**
	 * 
	 * @return
	 */
	public Jugador getJugadorElim() {
		return jugadorElim;
	}

	/**
	 * 
	 * @param jugadorElim
	 */
	public void setJugadorElim(Jugador jugadorElim) {
		this.jugadorElim = jugadorElim;
	}

	/**
	 * 
	 * @return
	 */
	public Jugador getJugadorBaja() {
		return jugadorBaja;
	}

	/**
	 * 
	 * @param jugadorBaja
	 */
	public void setJugadorBaja(Jugador jugadorBaja) {
		this.jugadorBaja = jugadorBaja;
	}

	/**
	 * 
	 * @return
	 */
	public Jugador getJugadorAlta() {
		return jugadorAlta;
	}

	/**
	 * 
	 * @param jugadorAlta
	 */
	public void setJugadorAlta(Jugador jugadorAlta) {
		this.jugadorAlta = jugadorAlta;
	}

	/**
	 * 
	 * @return
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * 
	 * @param nombre
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	/**
	 * 
	 * @return
	 */
	public String getApellidos() {
		return apellidos;
	}

	/**
	 * 
	 * @param apellidos
	 */
	public void setApellidos(String apellidos) {
		this.apellidos = apellidos;
	}

	/**
	 * 
	 * @return
	 */
	public Temporada getTemporada() {
		return temporada;
	}

	/**
	 * 
	 * @param temporada
	 */
	public void setTemporada(Temporada temporada) {
		this.temporada = temporada;
	}

	/**
	 * 
	 * @return
	 */
	public Equipo getEquipo() {
		return equipo;
	}

	/**
	 * 
	 * @param equipo
	 */
	public void setEquipo(Equipo equipo) {
		this.equipo = equipo;
	}

	/**
	 * 
	 * @return
	 */
	public ProvinciaDic getProvincia() {
		return provincia;
	}

	/**
	 * 
	 * @param provincia
	 */
	public void setProvincia(ProvinciaDic provincia) {
		this.provincia = provincia;
	}

	/**
	 * 
	 * @return
	 */
	public MunicipioDic getMunicipio() {
		return municipio;
	}

	/**
	 * 
	 * @param municipio
	 */
	public void setMunicipio(MunicipioDic municipio) {
		this.municipio = municipio;
	}

	/**
	 * 
	 * @return
	 */
	public Integer getEdad() {
		return edad;
	}

	/**
	 * 
	 * @param edad
	 */
	public void setEdad(Integer edad) {
		this.edad = edad;
	}

	/**
	 * 
	 * @return
	 */
	public PosicionDic getPosicion() {
		return posicion;
	}

	/**
	 * 
	 * @param posicion
	 */
	public void setPosicion(PosicionDic posicion) {
		this.posicion = posicion;
	}

	/**
	 * 
	 * @return
	 */
	public int getActivo() {
		return activo;
	}

	/**
	 * 
	 * @param activo
	 */
	public void setActivo(int activo) {
		this.activo = activo;
	}

	/**
	 * 
	 * @return
	 */
	public int getTotalRes() {
		return totalRes;
	}

	/**
	 * 
	 * @param totalRes
	 */
	public void setTotalRes(int totalRes) {
		this.totalRes = totalRes;
	}

	/**
	 * 
	 * @return
	 */
	public List<ProvinciaDic> getListaProvincias() {
		return listaProvincias;
	}

	/**
	 * 
	 * @param listaProvincias
	 */
	public void setListaProvincias(List<ProvinciaDic> listaProvincias) {
		this.listaProvincias = listaProvincias;
	}

	/**
	 * 
	 * @return
	 */
	public List<MunicipioDic> getListaMunicipios() {
		if (provincia != null) {
			listaMunicipios = municipioService.getList(provincia);
		}
		return listaMunicipios;
	}

	/**
	 * 
	 * @param listaMunicipios
	 */
	public void setListaMunicipios(List<MunicipioDic> listaMunicipios) {
		this.listaMunicipios = listaMunicipios;
	}

	/**
	 * 
	 * @return
	 */
	public List<Temporada> getListaTemporadas() {
		return listaTemporadas;
	}

	/**
	 * 
	 * @param listaTemporadas
	 */
	public void setListaTemporadas(List<Temporada> listaTemporadas) {
		this.listaTemporadas = listaTemporadas;
	}

	/**
	 * 
	 * @return
	 */
	public List<Equipo> getListaEquipos() {
		return listaEquipos;
	}

	/**
	 * 
	 * @param listaEquipos
	 */
	public void setListaEquipos(List<Equipo> listaEquipos) {
		this.listaEquipos = listaEquipos;
	}

	/**
	 * 
	 * @return
	 */
	public List<PosicionDic> getListaPosiciones() {
		return listaPosiciones;
	}

	/**
	 * 
	 * @param listaPosiciones
	 */
	public void setListaPosiciones(List<PosicionDic> listaPosiciones) {
		this.listaPosiciones = listaPosiciones;
	}

	/**
	 * 
	 * @return
	 */
	public List<Jugador> getJugadores() {
		return jugadores;
	}

	/**
	 * 
	 * @param jugadores
	 */
	public void setJugadores(List<Jugador> jugadores) {
		this.jugadores = jugadores;
	}

	/**
	 * 
	 * @return
	 */
	public Jugador getJugadorItem() {
		return jugadorItem;
	}

	/**
	 * 
	 * @param jugadorItem
	 */
	public void setJugadorItem(Jugador jugadorItem) {
		this.jugadorItem = jugadorItem;
	}

	/**
	 * 
	 * @return
	 */
	public String getNombreLote() {
		return nombreLote;
	}

	/**
	 * 
	 * @param nombreLote
	 */
	public void setNombreLote(String nombreLote) {
		this.nombreLote = nombreLote;
	}

	/**
	 * 
	 * @return
	 */
	public String getApellidosLote() {
		return apellidosLote;
	}

	/**
	 * 
	 * @param apellidosLote
	 */
	public void setApellidosLote(String apellidosLote) {
		this.apellidosLote = apellidosLote;
	}

	/**
	 * 
	 * @return
	 */
	public Equipo getEquipoLote() {
		return equipoLote;
	}

	/**
	 * 
	 * @param equipoLote
	 */
	public void setEquipoLote(Equipo equipoLote) {
		this.equipoLote = equipoLote;
	}

	/**
	 * 
	 * @return
	 */
	public ProvinciaDic getProvinciaLote() {
		return provinciaLote;
	}

	/**
	 * 
	 * @param provinciaLote
	 */
	public void setProvinciaLote(ProvinciaDic provinciaLote) {
		this.provinciaLote = provinciaLote;
	}

	/**
	 * 
	 * @return
	 */
	public MunicipioDic getMunicipioLote() {
		return municipioLote;
	}

	/**
	 * 
	 * @param municipioLote
	 */
	public void setMunicipioLote(MunicipioDic municipioLote) {
		this.municipioLote = municipioLote;
	}

	/**
	 * 
	 * @return
	 */
	public List<ProvinciaDic> getListaProvinciasLote() {
		return listaProvinciasLote;
	}

	/**
	 * 
	 * @param listaProvinciasLote
	 */
	public void setListaProvinciasLote(List<ProvinciaDic> listaProvinciasLote) {
		this.listaProvinciasLote = listaProvinciasLote;
	}

	/**
	 * 
	 * @return
	 */
	public List<MunicipioDic> getListaMunicipiosLote() {
		if (provinciaLote != null) {
			listaMunicipiosLote = municipioService.getList(provinciaLote);
		}
		return listaMunicipiosLote;
	}

	/**
	 * 
	 * @param listaMunicipiosLote
	 */
	public void setListaMunicipiosLote(List<MunicipioDic> listaMunicipiosLote) {
		this.listaMunicipiosLote = listaMunicipiosLote;
	}

	/**
	 * 
	 * @return
	 */
	public List<Jugador> getJugadoresBus() {
		return jugadoresBus;
	}

	/**
	 * 
	 * @param jugadoresBus
	 */
	public void setJugadoresBus(List<Jugador> jugadoresBus) {
		this.jugadoresBus = jugadoresBus;
	}

	/**
	 * 
	 * @return
	 */
	public List<Jugador> getJugadoresSel() {
		return jugadoresSel;
	}

	/**
	 * 
	 * @param jugadoresSel
	 */
	public void setJugadoresSel(List<Jugador> jugadoresSel) {
		this.jugadoresSel = jugadoresSel;
	}

	/**
	 * 
	 * @return
	 */
	public int getTotalResLote() {
		return totalResLote;
	}

	/**
	 * 
	 * @param totalResLote
	 */
	public void setTotalResLote(int totalResLote) {
		this.totalResLote = totalResLote;
	}

	/**
	 * 
	 * @return
	 */
	public int getPestania() {
		return pestania;
	}

	/**
	 * 
	 * @param pestania
	 */
	public void setPestania(int pestania) {
		this.pestania = pestania;
	}
}
